/*
 * Created on Jan 19, 2005
 */
package com.scalar.chiptrack.operations.lotcorrection.actions;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.operations.lotcorrection.LotCorrection;
import com.scalar.chiptrack.operations.lotcorrection.forms.LotReworkForm;
import com.scalar.chiptrack.operations.process.Lot;
import com.scalar.chiptrack.operations.process.Product;
import com.scalar.chiptrack.operations.process.VendorLocation;
import com.scalar.chiptrack.operations.process.dao.LotDAO;
import com.scalar.chiptrack.operations.process.dao.PartNumber;
import com.scalar.chiptrack.operations.process.dao.ProductDao;
import com.scalar.chiptrack.operations.vendor.dao.VendorDAO;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.users.Functionality;
/**
 * @author Ravikanth
**/
public class LotReworkAction extends ChipTrackAction
{
	private static final String ACTION_NAME = "/lotRework.do";

	public ActionForward execute (ActionMapping mapping,
								 ActionForm form,
								 HttpServletRequest request,
								 HttpServletResponse response)
								 throws Exception
	{
		ActionForward actionForward = mapping.findForward( "lotRework" );
	   	HttpSession session = request.getSession();

	   	User user = ( User ) session.getAttribute ( SessionKeys.USER_KEY );
	   	if ( user == null )
	   	{
			session.setAttribute ( SessionKeys.SOURCE_PAGE_KEY, ACTION_NAME );
		   	return ( mapping.findForward ( "login" ) );
	   	}
        else
        {
            if ( user.isActionAllowed ( Functionality.LOT_CORRECTION, User.USER_ACTION_MODIFY ) )
            {
                request.setAttribute ( "showMessage", "FALSE" );
            }
            else
            {
                request.setAttribute ( "showMessage", "TRUE" );
            }
        }

	   	HashMap errors	= new HashMap();
	   	HashMap info    	= new HashMap();
	   	String  action  	= request.getParameter( "action" );
		LotReworkForm lotReworkForm = ( LotReworkForm )form;
	   
		if( action == null || "null".equalsIgnoreCase( action ) )
		{
			session.setAttribute( "processList", getProcessList() );
			session.removeAttribute( "productList" );
			session.removeAttribute( "locationList" );
			session.removeAttribute( "lotNumberList" );
			session.removeAttribute( "newProcessList" );
			session.removeAttribute( "newProductList" );
			session.removeAttribute( "newLocationList" );
			session.setAttribute( "showNewLotInfo", "false" );
			lotReworkForm.setProcessType( "" );
			lotReworkForm.setProcessStepId( "" );
			lotReworkForm.setLocationId( "" );
			lotReworkForm.setLotId( "" );
			lotReworkForm.setDateIn( "" );
			lotReworkForm.setQtyIn( 0 );
		}
		else if( "loadProducts".equals( action ) )
		{
			try
			{
				session.setAttribute( "productList", getProductList( lotReworkForm.getProcessType() ) );
				session.removeAttribute( "locationList" );
				session.removeAttribute( "lotNumberList" );
				session.removeAttribute( "selectedCSIds" );
				session.removeAttribute( "newProcessList" );
				session.removeAttribute( "newProductList" );
				session.removeAttribute( "newLocationList" );
				session.setAttribute( "showNewLotInfo", "false" );
				lotReworkForm.setProcessStepId( "" );
				lotReworkForm.setLocationId( "" );
				lotReworkForm.setLotId( "" );
				lotReworkForm.setDateIn( "" );
				lotReworkForm.setQtyIn( 0 );
				lotReworkForm.setNewProcessType( "" );
				lotReworkForm.setNewProcessStepId( "" );
				lotReworkForm.setNewLocationId( "" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );
			}
			catch( Exception e )
			{
				errors.put( "Error while retreiving the product list", null );
			}
		}
		else if( "loadLocations".equals( action ) )
		{
			try
			{
				session.setAttribute( "locationList", getLocationList( lotReworkForm.getProcessStepId() ) );
				session.removeAttribute( "lotNumberList" );
				session.removeAttribute( "selectedCSIds" );
				session.removeAttribute( "newProcessList" );
				session.removeAttribute( "newProductList" );
				session.removeAttribute( "newLocationList" );
				session.setAttribute( "showNewLotInfo", "false" );
				lotReworkForm.setLocationId( "" );
				lotReworkForm.setLotId( "" );
				lotReworkForm.setDateIn( "" );
				lotReworkForm.setQtyIn( 0 );
				lotReworkForm.setNewProcessType( "" );
				lotReworkForm.setNewProcessStepId( "" );
				lotReworkForm.setNewLocationId( "" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );
			}
			catch( Exception e )
			{
				errors.put( "Error while retreiving the location list", null );
			}
		}
		else if( "loadLotNumbers".equals( action ) )
		{
			try
			{
				session.removeAttribute( "selectedCSIds" );
				session.removeAttribute( "newProcessList" );
				session.removeAttribute( "newProductList" );
				session.removeAttribute( "newLocationList" );
				session.setAttribute( "showNewLotInfo", "false" );
				session.setAttribute( "lotNumberList", getLotList( lotReworkForm.getProcessStepId(), lotReworkForm.getLocationId() ) );
				lotReworkForm.setLotId( "" );
				lotReworkForm.setDateIn( "" );
				lotReworkForm.setQtyIn( 0 );
				lotReworkForm.setNewProcessType( "" );
				lotReworkForm.setNewProcessStepId( "" );
				lotReworkForm.setNewLocationId( "" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );
			}
			catch( Exception e )
			{
				errors.put( "Error while retreiving the lot numbers list", null );
			}
		}
		else if( "loadLot".equals( action ) )
		{
			try
			{
				LotCorrection lotCorrection = LotDAO.fetchLotInformation( lotReworkForm.getLotId() );
				if( lotCorrection != null )
				{
					lotReworkForm.setDateIn( lotCorrection.getDateIn() );
					lotReworkForm.setQtyIn( Integer.parseInt( lotCorrection.getQuantityIn() ) );
				}
				else
				{
					System.out.println( "Could not fetch the Lot Information" );
					throw new ScalarException( "Could not fetch lot information for Lot "+ lotReworkForm.getLotId(), null );
				}
				
				ArrayList newProcessList = getNewProcessList( Integer.parseInt( lotReworkForm.getProcessStepId() ) ) ;
				
				if( newProcessList != null && newProcessList.isEmpty() == false )
				{
					session.setAttribute( "newProcessList", newProcessList );	
				}
				else
				{
					errors.put( "There is no process after Assembly for Rework", null );
				}
				session.removeAttribute( "newProductList" );
				session.removeAttribute( "newLocationList" );
				session.setAttribute( "showNewLotInfo", "false" );
				lotReworkForm.setNewProcessType( "" );
				lotReworkForm.setNewProcessStepId( "" );
				lotReworkForm.setNewLocationId( "" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );
			}
			catch( Exception e )
			{
				e.printStackTrace();
				errors.put( "Error while retreiving the lot", null );
				throw new ScalarException( "Could not fetch lot information for Lot "+ lotReworkForm.getLotId(), null );
			}
		}
		else if( "loadNewProducts".equals( action ) )
		{
			try
			{
				ArrayList newProductList = getNewProductList( Integer.parseInt( lotReworkForm.getProcessStepId() ), lotReworkForm.getNewProcessType() );
				
				if( newProductList != null && newProductList.isEmpty() == false )
				{
					session.setAttribute( "newProductList", newProductList );	
				}
				else
				{
					errors.put( "There is no Products for the Process for Rework", null );
				}
				session.removeAttribute( "newLocationList" );
				session.setAttribute( "showNewLotInfo", "false" );
				lotReworkForm.setNewProcessStepId( "" );
				lotReworkForm.setNewLocationId( "" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );

			}
			catch( Exception e )
			{
				e.printStackTrace();
				errors.put( "Error while retreiving the new product list", null );
			}
		}
		else if( "loadNewLocations".equals( action ) )
		{
			try
			{
				session.setAttribute( "newLocationList", getLocationList( lotReworkForm.getNewProcessStepId() ) );
			}
			catch( Exception e )
			{
				errors.put( "Error while retreiving the new location list", null );
			}
			session.setAttribute( "showNewLotInfo", "false" );
			lotReworkForm.setNewLocationId( "" );
			lotReworkForm.setNewQtyIn( 0 );
			lotReworkForm.setNewDateIn( "" );

		}
		else if( "enterNewLot".equals( action ) )
		{
			try
			{
                LotCorrection lotCorrection = LotDAO.fetchLotInformation( lotReworkForm.getLotId(), lotReworkForm.getNewProcessStepId(), lotReworkForm.getNewLocationId() );
				if( lotCorrection != null )
				{
					lotReworkForm.setPrevLotExists( true );
					lotReworkForm.setPrevQtyIn( lotCorrection.getQuantityIn() );
					lotReworkForm.setPrevDateIn( lotCorrection.getDateIn() );
				}
				else
				{
					lotReworkForm.setPrevLotExists( false );
				}
				session.setAttribute( "showNewLotInfo", "true" );
				lotReworkForm.setNewQtyIn( 0 );
				lotReworkForm.setNewDateIn( "" );
                lotReworkForm.setExistingInventory(1);
			}
			catch( Exception e )
			{
				e.printStackTrace();
				errors.put( "Error while retreiving the new location list", null );
			}
		}
        else if( "allLotInfo".equals( action ) )
		{
            LotCorrection lotCorrection = null;
            ArrayList allLotsList   = null;
            ArrayList lotsList      = null;
            String lotNo            = null;
            String newlotId         = null;
			try
			{
                String lotId        = request.getParameter("LotId");
                lotsList            = LotDAO.getAllLotDetails( lotId );

                for ( int i=0; i<lotsList.size(); i++ )
                {
                    lotCorrection   = (LotCorrection)lotsList.get(i);
                }

                lotNo = lotCorrection.getLotNumber();

                newlotId = LotDAO.getLotId( lotNo , lotReworkForm.getNewLocationId(), lotReworkForm.getNewProcessStepId()  );

                if ( newlotId != null && newlotId.length() > 0 )
                {
                    allLotsList = LotDAO.getAllLotDetails( newlotId );
                }

                request.setAttribute("allLotsList", allLotsList );
				session.setAttribute( "showNewLotInfo", "true" );

                actionForward = mapping.findForward( "alllotInfo" );
			}
			catch( Exception e )
			{
				e.printStackTrace();
				errors.put( "Error while retreiving the Lot history list", null );
			}
		}
		else if( "saveLot".equals( action ) )
		{
			try
			{
				//System.out.println( "I am saving the data " );
				LotDAO.saveReworkLot( lotReworkForm );
				info.put( "Lot information saved successfully ", null );
				actionForward = mapping.findForward( "saveSuccess" );
			}
			catch( Exception e )
			{
				errors.put( "Could not save the Lot Information", null );
			}
		}
		if( !errors.isEmpty() )
		{
			request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
		}

		if( !info.isEmpty() )
		{
			request.setAttribute( SessionKeys.INFO_MESSAGES, info );
		}

	   return actionForward;
   }
   
	/**
	* Returns an arraylist of processes
	*
	* @return
	*/
   	public ArrayList getProcessList()
   	{
		ArrayList processList = new ArrayList();
		processList.add( new org.apache.struts.util.LabelValueBean( "TEST", "TEST" ) );
		processList.add( new org.apache.struts.util.LabelValueBean( "CLASS STORE", "Class Store" ) );
		processList.add( new org.apache.struts.util.LabelValueBean( "MARK&PACK", "Mark and Pack" ) );
		processList.add( new org.apache.struts.util.LabelValueBean( "FINISHED GOODS", "Finished Goods" ) );
		return processList;
	}
   
	public ArrayList getNewProcessList( int processStep_id ) throws ScalarException
   	{
   		ArrayList processList 		= new ArrayList();
		ArrayList tempProcessList 	= new ArrayList();
		Product product 			= null;
		LabelValueBean bean 		= null;
		boolean insert 				= true; 
		
		try
		{
			tempProcessList = ProductDao.fetchPreviousProcesses( processStep_id );
			if( tempProcessList != null && tempProcessList.isEmpty() == false )
			{
				for( int i = 0; i < tempProcessList.size(); i++ )
				{
					product = (Product)tempProcessList.get( i );
					if( product.getProcessStepId() != processStep_id && !product.getBaseProcessType().equalsIgnoreCase( "Fab" ) && !product.getBaseProcessType().equalsIgnoreCase( "SORT" )  && !product.getBaseProcessType().equalsIgnoreCase( "Die Bank" ) && !product.getBaseProcessType().equalsIgnoreCase( "Wafer Store" ) && !product.getBaseProcessType().equalsIgnoreCase( "Assembly" ) )
					{
						insert = true;
						//bean = new LabelValueBean( product.getBaseProcessType(), product.getBaseProcessType() );
						for( int j = 0; j < processList.size(); j++ )
						{
							
							bean = (LabelValueBean)processList.get( j );
							if( bean.getValue().equalsIgnoreCase( product.getBaseProcessType() ) )
							{
								insert = false;
								break;
							}
						}
						
						if( insert )
						{
							processList.add( new org.apache.struts.util.LabelValueBean( product.getBaseProcessType(), product.getBaseProcessType() ) );						
						}
					}
				}
			}
		}
		catch( ScalarException e )
		{
			e.printStackTrace();
			throw new ScalarException( "Could not fetch the Previous Step Information", null ); 
		}
		return processList;
   	}
   
   /**
	* Returns the list of part number in the given process
	*
	* @param process
	* @return
	*/
	public static ArrayList getProductList( String process ) throws ScalarException
   	{
		ArrayList partNumberSelectList 	= new ArrayList ();
	   	ArrayList partNumberList       	= null;
	   	PartNumber partNumber 			= null;

	   	if( ( "FAB".equals( process ) ) || ( "SORT".equals( process ) ) || ( "ASSEMBLY".equals( process ) ) || ( "TEST".equals( process ) ) )
	   	{
			partNumberList = ProductDao.getPartNumber ( process );
		   	for ( int i = 0; i < partNumberList.size (); i++ )
		   	{
				partNumber = ( PartNumber ) partNumberList.get ( i );
				partNumberSelectList.add ( new org.apache.struts.util.LabelValueBean ( partNumber.getPartNumber (), partNumber.getProcessStepId() ) );
		   	}
	   	}
	   	else if ( ( "Wafer Store".equals( process ) ) || ( "Die Bank".equals( process ) ) || ( "Class Store".equals( process ) ) || ( "Mark and Pack".equals( process ) ) || ( "Finished Goods".equals( process ) ) )
	   	{
			String processSearchString = "";
		   	if( ( "Wafer Store".equals( process ) ) )
		   	{
				processSearchString = "wafer%";
		   	}
		   	if( ( "Die Bank".equals( process ) ) )
		   	{
				processSearchString = "die%";
		   	}
		   	if( ( "Class Store".equals( process ) ) )
		   	{
				processSearchString = "class%";
		   	}
		   	if( ( "Mark and Pack".equals( process ) ) )
		   	{
				processSearchString = "mark%";
		   	}
		   	if( ( "Finished Goods".equals( process ) ) )
		   	{
				processSearchString = "finished%";
		   	}
		   	
		   	partNumberList = ProductDao.getInventoryPartNumber( processSearchString );
		   	
		   	for( int i = 0; i < partNumberList.size(); i++ )
		   	{
				partNumber 		= (PartNumber)partNumberList.get(i);
			   	String partNo 	= partNumber.getPartNumber();
			   	StringTokenizer someValue = new StringTokenizer( partNo, "/" );
			   	String finalPartNo 	=  someValue.nextToken();
				partNumberSelectList.add( new LabelValueBean( finalPartNo, partNumber.getProcessStepId() ) );
		   	}
	   	}

	   	return partNumberSelectList;
   }

   /**
	 * @param processStep_Id
    *  @param  process
	 * @return
	 */
	private ArrayList getNewProductList( int processStep_Id, String process ) throws ScalarException
	{
		ArrayList partNumberList       	= new ArrayList();
		ArrayList tempPartNumberList    = null;
		Product product					= null;

		try
		{
			tempPartNumberList = ProductDao.fetchPreviousProcesses( processStep_Id );
			
			if( tempPartNumberList != null && tempPartNumberList.isEmpty() == false )
			{
				for( int i = 0; i < tempPartNumberList.size(); i++ )
				{
					product = (Product)tempPartNumberList.get( i );
					
					if( product.getProcessStepId() != processStep_Id && product.getBaseProcessType().equalsIgnoreCase( process ) )
					{
						if( "TEST".equalsIgnoreCase( process ) || "SORT".equalsIgnoreCase( process ) )
						{
							partNumberList.add( new org.apache.struts.util.LabelValueBean( product.getPartNumber()+"/"+product.getProcessType() , product.getProcessStepId()+"" ) );
						}
						else
						{	
							partNumberList.add( new org.apache.struts.util.LabelValueBean( product.getPartNumber(), product.getProcessStepId()+"" ) );
						}
					}
				}
			}
		}
		catch( ScalarException e )
		{
			e.printStackTrace();
			throw new ScalarException( "Could not fetch the Previous Step Information", null ); 
		}
		
		return partNumberList;
	}

   
   /**
	* Returns the list of locations of this process step
	*
	* @param processStepId
	* @return
	*/
   	public static ArrayList getLocationList( String processStepId ) throws ScalarException
   	{
	   	ArrayList locationList = VendorDAO.getSelectedLocations ( Integer.parseInt ( processStepId ) );
	   	ArrayList locationSelectList = new ArrayList();
	   	VendorLocation vendorLocation = null;

	   	for ( int i = 0; i < locationList.size (); i++ )
	   	{
			vendorLocation = ( VendorLocation ) locationList.get ( i );
			locationSelectList.add ( new org.apache.struts.util.LabelValueBean ( vendorLocation.getLocationName(), vendorLocation.getLocationID() ) );
	   	}
	   	return locationSelectList;
   	}

	/**
	 * Returns the list of lots matching the given processStepId and locationId
	 *
	 * @param processStepId
	 * @param locationId
	 * @return
	 */
	private ArrayList getLotList( String processStepId, String locationId ) throws ScalarException
	{
		ArrayList lotList = new ArrayList();
		Lot lot = null;
		ArrayList lotNumberList = LotDAO.getAllLots( processStepId, locationId );
		lotList = new ArrayList ();

		for ( int i = 0; i < lotNumberList.size (); i++ )
		{
			lot = ( Lot ) lotNumberList.get ( i );

			if( "Running".equalsIgnoreCase( lot.getStatus() ) )
			{
				lotList.add ( new org.apache.struts.util.LabelValueBean ( lot.getLotNumber (), lot.getLotId () ) );
			}
		}
		return lotList;
	}
}
